<?php
require_once( 'cos-php-sdk-v5/vendor/autoload.php');
require_once( 'Ifsnop/Mysqldump/Mysqldump.php' );
use Ifsnop\Mysqldump as IMysqldump;

//删除任务
function backup_cos_delete_cron() {
	if( wp_next_scheduled( 'backups_cos_cron' ) )
		wp_clear_scheduled_hook( 'backups_cos_cron' );
}
register_deactivation_hook( __FILE__, 'backup_cos_delete_cron' );
register_uninstall_hook( __FILE__, 'backup_cos_delete_cron' );
//任务执行函数
function backup_cos_cron_fun() {
	backup_cos_start();
}
add_action( 'backups_cos_cron', 'backup_cos_cron_fun' );
//添加定时任务周期
function backup_cos_add_schedules( $schedules ) {
  $schedules['weekly'] = array(
    'interval' => 604800,
    'display' => '每周一次',
  );
  $schedules['monthly'] = array(
    'interval' => 2592000,
    'display' => '每月一次',
  );
  return $schedules;
}
add_filter('cron_schedules', 'backup_cos_add_schedules', 10, 1);
//初始化
function backup_cos_config() {
	$options = get_option('backups_cos');
	$options = unserialize($options);
	$class = new Qcloud\Cos\Client(array(
		'region' => $options['region'],
		'credentials' => array(
		    'appId' => $options['APP_ID'],
		    'secretId' => $options['SecretID'],
		    'secretKey' => $options['SecretKey'],
		),
	));

	$domain = preg_replace( '|https?://([^/]+)|', '$1', get_option( 'home' ) );
	$domain = str_replace('/', '-', $domain);

	$cosClient['Bucket_Name'] = $options['Bucket_Name'];
	$cosClient['class'] = $class;
	$cosClient['domain'] = $domain;
	return $cosClient;
}
//发送邮件
function backup_cos_mail($error) {
	$blogname = get_bloginfo( 'name' );
	$adminemail = get_bloginfo('admin_email');
	$mail_title = $blogname . '备份文件到COS失败通知';
	$mail_txt = '以下文件备份失败：' . "\n" . $error;
	$headers[] = 'From: '. $blogname .' < ' . $adminemail . '>';
	wp_mail( $blogname . ' <' . $adminemail . '>', $mail_title, $mail_txt, $headers );
}
//备份数据库
function backup_cos_start() {
	if(function_exists('set_time_limit')) set_time_limit(0);
	$cosClient = backup_cos_config();
	$timestamp = current_time( 'timestamp' );
	$suffix = date( 'j', $timestamp );
	$error = '';
	try {
		$sql_temp = tempnam( sys_get_temp_dir(), 'cos_' );
		$dump = new IMysqldump\Mysqldump('mysql:host=' . DB_HOST . ';dbname=' . DB_NAME, DB_USER, DB_PASSWORD);
		$dump->start($sql_temp);
	} catch (\Exception $e) {
		$error = $e->getMessage();
	}
	if( $error == '' ) {
		$file_size = filesize($sql_temp);
		$handle = fopen($sql_temp, 'rb');
		$sql_content = fread($handle, $file_size);
		$file_temp = tempnam( sys_get_temp_dir(), 'cos_' );
		$file_temp = $file_temp . '.zip';
		$save_file = '/' . $cosClient['domain'] . '/' . $cosClient['domain'] . '_mysql_' . $suffix . '.zip';
		$zip = new ZipArchive;
		if ( $zip->open( $file_temp, ZIPARCHIVE::CREATE ) === TRUE ) {
			$zip->addFromString( DB_NAME . '.sql', $sql_content );
			$zip->close();
		}

		try {
			$result = $cosClient['class']->Upload(
				$bucket = $cosClient['Bucket_Name'],
				$key = $save_file,
				$body = fopen($file_temp, 'rb'));
		} catch (\Exception $e) {
			$error = $e;
		}

		fclose($handle);
		unlink($sql_temp);
		unlink($file_temp);
	}
	return $error;
}
//获取所有版本图片路径
function backup_cos_attachments($meta) {
	$upload_path = get_option( 'upload_path');
	if(!$upload_path) $upload_path = 'wp-content/uploads';
	$upload_path = rtrim($upload_path, '/');
	$basepath = $upload_path . '/' . str_replace(basename($meta['file']), '', $meta['file']);
	$attachments[] = $basepath . basename($meta['file']);
	if(!empty($meta['sizes'])) {
		foreach($meta['sizes'] as $val) {
			if(!$val['file']) continue;
			$attachments[] = $basepath . $val['file'];
		}
	}
	$attachments = array_unique($attachments);
	return $attachments;
}
//上传图片
function backup_cos_upload_pic($data, $attachment_id) {
	if(!wp_attachment_is_image($attachment_id)) return $data;
	if(!$data['file']) return $data;
	$cosClient = backup_cos_config();
	$attachments = backup_cos_attachments($data);
	$error = '';
	foreach($attachments as $val) {
		if(!$val || !file_exists(ABSPATH . $val) ) continue;
		try {
			$result = $cosClient['class']->putObject(array(
				'Bucket' => $cosClient['Bucket_Name'],
				'Key' => '/' . $cosClient['domain'] . '/' . $val,
				'Body' => fopen(ABSPATH . $val, 'rb')
			));
		} catch (\Exception $e) {
			$error .= '/' . $cosClient['domain'] . '/' . $val . "\n";
		}
	}
	if($error) {
		backup_cos_mail($error);
	}
	return $data;
}
add_filter('wp_generate_attachment_metadata', 'backup_cos_upload_pic', 10, 2);
//上传文件
function backup_cos_upload_file($attachment_id) {
	if(wp_attachment_is_image($attachment_id)) return false;
	$filepath = get_attached_file($attachment_id);
	$savepath = str_replace(ABSPATH, '', $filepath);
	$cosClient = backup_cos_config();
	try {
		$result = $cosClient['class']->putObject(array(
			'Bucket' => $cosClient['Bucket_Name'],
			'Key' => '/' . $cosClient['domain'] . '/' . $savepath,
			'Body' => fopen($filepath, 'rb')
		));
	} catch (\Exception $e) {
		backup_cos_mail('/' . $cosClient['domain'] . '/' . $savepath);
	}
}
add_action( 'add_attachment', 'backup_cos_upload_file', 10, 1 );
//删除附件
function backup_cos_delete_attachment($attachment_id) {
	$cosClient = backup_cos_config();
	if(wp_attachment_is_image($attachment_id)) {
		$meta = wp_get_attachment_metadata($attachment_id);
		if(!$meta['file']) return;
		$attachments = backup_cos_attachments($meta);
		foreach($attachments as $val) {
			if(!$val) continue;
			try {
				$result = $cosClient['class']->deleteObject(array(
					'Bucket' => $cosClient['Bucket_Name'],
					'Key' => '/' . $cosClient['domain'] . '/' . $val,
				));
			} catch (\Exception $e) {

			}
		}
	} else {
		$filepath = get_attached_file($attachment_id);
		$savepath = str_replace(ABSPATH, '', $filepath);
		if($savepath) {
			try {
				$result = $cosClient['class']->deleteObject(array(
					'Bucket' => $cosClient['Bucket_Name'],
					'Key' => '/' . $cosClient['domain'] . '/' . $savepath,
				));
			} catch (\Exception $e) {

			}
		}
	}
}
add_action( 'delete_attachment', 'backup_cos_delete_attachment', 10, 1 );
?>
